package com.beiding.editanalyzeframe;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 丁常磊
 * @date 2021/11/30 13:34
 */

public class DocUtils {

    public static CompareResult compare(List<Line> base, List<Line> target,AnalyzeConfig analyzeConfig) {
        CompareResult compareResult = new CompareResult();
        compare(base, target, compareResult,analyzeConfig);
        return compareResult;
    }

    private static void compare(List<Line> base, List<Line> target, CompareResult compareResult,AnalyzeConfig analyzeConfig) {

        if (base.size() == 0 && target.size() == 0) {
            return;
        }

        //先找出最大相似
//        CommonUtils.MaxSameSegment maxSameSegment = CommonUtils.maxSameSegment(base, target);

        //已经排好序了
        List<CommonUtils.MaxSameSegment> maxSameSegments = CommonUtils.maxSameSegment(base, target);

        if (maxSameSegments.size() == 0) {
            //没有任何相同

            checkNotSame(base, target, compareResult,analyzeConfig);


        } else {
            //第一段相同的位置
            CommonUtils.MaxSameSegment maxSameSegment = maxSameSegments.get(0);

            //相同前一段
            checkNotSame(
                    base.subList(0, maxSameSegment.getStartA()),
                    target.subList(0, maxSameSegment.getStartB()),
                    compareResult,analyzeConfig);

            addSame(base, target, compareResult, maxSameSegment);

            //其余相同位置
            for (int j = 1; j < maxSameSegments.size(); j++) {


                CommonUtils.MaxSameSegment last = maxSameSegment;
                maxSameSegment = maxSameSegments.get(j);

                //在两个之间会有一个不相同的

                checkNotSame(base.subList(last.getStartA() + last.getLen(), maxSameSegment.getStartA()),
                        target.subList(last.getStartB() + last.getLen(), maxSameSegment.getStartB()),
                        compareResult,analyzeConfig);


                addSame(base, target, compareResult, maxSameSegment);


            }


            maxSameSegment = maxSameSegments.get(maxSameSegments.size() - 1);

            //相同后一段

            checkNotSame(base.subList(maxSameSegment.getStartA() + maxSameSegment.getLen(), base.size()),
                    target.subList(maxSameSegment.getStartB() + maxSameSegment.getLen(), target.size()),
                    compareResult,analyzeConfig);


        }

    }

    private static void addSame(List<Line> base, List<Line> target, CompareResult compareResult, CommonUtils.MaxSameSegment maxSameSegment) {
        //添加相同区段
        for (int i = 0; i < maxSameSegment.getLen(); i++) {
            Line la = base.get(maxSameSegment.getStartA() + i);
            Line lb = target.get(maxSameSegment.getStartB() + i);
            compareResult.sameLinePairs.add(new LinePair(la, lb));
        }

    }

    private static void checkNotSame(List<Line> base, List<Line> target, CompareResult compareResult,AnalyzeConfig analyzeConfig) {
        //相似度识别
        CommonUtils.MaxEditPossibilityResult maxEditPossibilityResult = CommonUtils.maxEditPossibility(base, target,analyzeConfig);


        List<Line> add = new ArrayList<>(target);
        List<Line> remove = new ArrayList<>(base);

        //最大编辑可能性
        if (maxEditPossibilityResult.getEditLinePairs().size() > 0) {
            for (LinePair editLinePair : maxEditPossibilityResult.getEditLinePairs()) {
                compareResult.editLinePairs.add(editLinePair);
                add.remove(editLinePair.getLineInTarget());
                remove.remove(editLinePair.getLineInSource());
            }
        }

        compareResult.addLines.addAll(add);
        compareResult.removeLines.addAll(remove);
    }

    /**
     * 创建分析行
     *
     * @param compare
     * @return
     */
    public static List<AnalyseLine> createAnalyseLines(CompareResult compare) {

        List<AnalyseLine> analyseLines = new ArrayList<>();

        for (LinePair editLinePair : compare.getEditLinePairs()) {
            AnalyseLine analyseLine = new AnalyseLine();
            analyseLine.status = LineStatus.EDIT;
            analyseLine.sourceLine = editLinePair.getLineInSource();
            analyseLine.targetLine = editLinePair.getLineInTarget();
            analyseLines.add(analyseLine);
        }

        for (LinePair sameLinePair : compare.getSameLinePairs()) {
            AnalyseLine analyseLine = new AnalyseLine();
            analyseLine.status = LineStatus.SAME;
            analyseLine.sourceLine = sameLinePair.getLineInSource();
            analyseLine.targetLine = sameLinePair.getLineInTarget();
            analyseLines.add(analyseLine);
        }

        for (Line removeLine : compare.getRemoveLines()) {
            AnalyseLine analyseLine = new AnalyseLine();
            analyseLine.status = LineStatus.DELETE;
            analyseLine.sourceLine = removeLine;
            analyseLines.add(analyseLine);
        }

        for (Line addLine : compare.getAddLines()) {
            AnalyseLine analyseLine = new AnalyseLine();
            analyseLine.status = LineStatus.ADD;
            analyseLine.targetLine = addLine;
            analyseLines.add(analyseLine);
        }

        //排序,只要保证来自相同文档的行的有序性即可
        SortUtils.sort(analyseLines, (a, b) -> {

            //在同一个文档中 按照文档顺序排序
            if (a.sourceLine != null && b.sourceLine != null) {
                return a.sourceLine.getLineNumber() - b.sourceLine.getLineNumber();
            } else if (a.targetLine != null && b.targetLine != null) {
                return a.targetLine.getLineNumber() - b.targetLine.getLineNumber();
            }


            //不在同一个文档中,有的靠前
/*
            Line ca = null;
            if (a.targetLine != null) {
                ca = a.targetLine;
            } else {
                ca = a.sourceLine;
            }

            Line cb = null;
            if (b.targetLine != null) {
                cb = b.targetLine;
            } else {
                cb = b.sourceLine;
            }

*/

            return 0;

        });

        return analyseLines;
    }


}
